package com.treasure.mall.biz.service.core.product.impl;

import com.alibaba.fastjson.JSON;
import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.AuthHelper;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.base.UserDetails;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.condition.ProductApiSearchCondition;
import com.treasure.mall.biz.dto.condition.ProductSearchCondition;
import com.treasure.mall.biz.dto.product.LiveProductSaveDTO;
import com.treasure.mall.biz.dto.product.NormalProductSaveDTO;
import com.treasure.mall.biz.entity.embeddable.MerchantData_;
import com.treasure.mall.biz.entity.product.CategoryPO;
import com.treasure.mall.biz.entity.product.ProductImgPO;
import com.treasure.mall.biz.entity.product.ProductPO;
import com.treasure.mall.biz.entity.product.ProductPO_;
import com.treasure.mall.biz.entity.user.MerchantPO;
import com.treasure.mall.biz.entity.user.MerchantPO_;
import com.treasure.mall.biz.entity.user.UserPO;
import com.treasure.mall.biz.mapstruct.ProductMapStruct;
import com.treasure.mall.biz.remote.live.TencentIMService;
import com.treasure.mall.biz.remote.live.dto.GoodsTargetMessageDTO;
import com.treasure.mall.biz.repository.product.CategoryRepository;
import com.treasure.mall.biz.repository.product.ProductImgRepository;
import com.treasure.mall.biz.repository.product.ProductRepository;
import com.treasure.mall.biz.repository.user.UserRepository;
import com.treasure.mall.biz.service.core.product.ProductService;
import com.treasure.mall.biz.service.core.user.MerchantService;
import com.treasure.mall.biz.vo.PageDataVO;
import com.treasure.mall.biz.vo.product.ProductApiDetailVo;
import com.treasure.mall.biz.vo.product.ProductApiVo;
import com.treasure.mall.zbq.common.MathUtils;
import com.treasure.mall.zbq.common.RegexUtils;
import com.treasure.mall.zbq.common.SqlDataReader;
import com.treasure.mall.zbq.common.StringUtilsExt;
import com.treasure.mall.zbq.common.base.ApiResult;
import com.treasure.mall.zbq.common.base.ResultCodeEnum;
import com.treasure.mall.zbq.common.exception.ApiException;
import com.treasure.mall.zbq.common.ienum.auction.AuctionEnums;
import com.treasure.mall.zbq.common.ienum.auth.RoleEnum;
import com.treasure.mall.zbq.common.ienum.base.CodeDescCommonEnum;
import com.treasure.mall.zbq.common.ienum.base.CodeDescEnumHelper;
import com.treasure.mall.zbq.common.ienum.product.ProductEnums;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wm
 */
@Slf4j
@Service
public class ProductServiceImpl extends AbstractSearchableCrudService<ProductPO, Long> implements ProductService {
    private ProductRepository productRepository;

    @Autowired
    private ProductImgRepository productImgRepository;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private TencentIMService tencentIMService;

    @Autowired
    protected ProductServiceImpl(ProductRepository repository) {
        super(repository);
        productRepository = repository;
    }

    @Override
    protected SpecificationAndSort<ProductPO> specificationAndSort(BaseSearchDTO searchDTO) {
        ProductSearchCondition condition = (ProductSearchCondition) searchDTO;
        UserDetails userDetails = AuthHelper.getPrincipal();
        if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
            condition.setMerchantId(userDetails.getId());
        }

        Specification<ProductPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(condition.getKeyword())) {
                predicates.add(cb.like(root.get(ProductPO_.PRODUCT_NAME), likeAll(condition.getKeyword())));
            }
            if (condition.getProductType() != null && condition.getProductType() != -1) {
                predicates.add(cb.equal(root.get(ProductPO_.productType), condition.getProductType()));
            }
            if (condition.getMerchantId() > 0) {
                predicates.add(cb.equal(root.get(ProductPO_.merchantPO).get(MerchantPO_.merchantId), condition.getMerchantId()));
            }

            //店铺名称
            if (StringUtils.isNotBlank(condition.getShopTitle())) {
                predicates.add(cb.like(root.get(ProductPO_.merchantPO).get(MerchantPO_.data).get(MerchantData_.title), likeAll(condition.getShopTitle())));
            }

            if (condition.getRoomId() > 0) {
                predicates.add(cb.equal(root.get(ProductPO_.roomId), condition.getRoomId()));
            }

            if (condition.getSaleType() != -1) {
                predicates.add(cb.equal(root.get(ProductPO_.saleType), CodeDescEnumHelper.getEnumTypeByCode(ProductEnums.SaleType.class, condition.getSaleType())));
            }
            predicates.add(cb.equal(root.get(ProductPO_.deleteFlag), 0));
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public ProductPO save(BaseSaveDTO saveDTO) {
        return null;
    }

    @Override
    public ApiResult saveNormalProduct(NormalProductSaveDTO saveDTO) {
        saveDTO.setProductType(ProductEnums.ProductType.NORMAL.getCode());
        boolean isAdd = saveDTO.getProductId() == null || saveDTO.getProductId() <= 0;
        if (isAdd) {
            return this.addNormalProduct(saveDTO);
        }
        return this.editNormalProduct(saveDTO);
    }

    @Override
    public ApiResult saveLiveProduct(LiveProductSaveDTO saveDTO) {
        saveDTO.setProductType(ProductEnums.ProductType.LIVE_BROADCAST.getCode());
        boolean isAdd = saveDTO.getProductId() == null || saveDTO.getProductId() <= 0;
        if (isAdd) {
            return this.addLiveProduct(saveDTO);
        }
        return this.editLiveProduct(saveDTO);
    }

    @Override
    public ApiResult delProduct(Long productId) {
        ProductPO po = productRepository.findById(productId).orElse(null);
        if (po == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "不存在");
        }
//        UserDetails userDetails = AuthHelper.getPrincipal();
//        if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
//            if (!po.getMerchantPO().getMerchantId().equals(userDetails.getId())) {
//                return ApiResult.errorWith(ResultCodeEnum.ERROR, "非法操作");
//            }
//        }
        po.setDeleteFlag(1);
        productRepository.save(po);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }

    @Override
    public ApiResult changeStatus(Long productId, Integer statusCode) {
        ProductPO po = productRepository.findById(productId).orElse(null);
        if (po == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "不存在");
        }
//        UserDetails userDetails = AuthHelper.getPrincipal();
//        if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
//            if (!po.getMerchantPO().getMerchantId().equals(userDetails.getId())) {
//                return ApiResult.errorWith(ResultCodeEnum.ERROR, "非法操作");
//            }
//        }
        po.setStatusCode(statusCode);
        productRepository.save(po);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }

    @Override
    public ApiResult changeTopStatus(Long productId, Integer statusCode) {
        ProductPO po = productRepository.findById(productId).orElse(null);
        if (po == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "不存在");
        }
//        UserDetails userDetails = AuthHelper.getPrincipal();
//        if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
//            if (!po.getMerchantPO().getMerchantId().equals(userDetails.getId())) {
//                return ApiResult.errorWith(ResultCodeEnum.ERROR, "非法操作");
//            }
//        }
        po.setRecommendFlag(statusCode);
        productRepository.save(po);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }


    @Override
    public void processExclusiveUser(List<ProductPO> productPOS) {
        List<Long> userIdList = new ArrayList<>();
        for (ProductPO po : productPOS) {
            if (po.getExclusiveUserId() == null || po.getExclusiveUserId() == 0) {
                continue;
            }
            if (!userIdList.contains(po.getExclusiveUserId())) {
                userIdList.add(po.getExclusiveUserId());
            }
        }
        if (userIdList.size() == 0) {
            return;
        }
        List<UserPO> userPOList = userRepository.getUserList(userIdList);
        Map<Long, UserPO> id2Po = userPOList.stream().collect(Collectors.toMap(UserPO::getUserId, Function.identity()));
        productPOS.forEach(x -> {
            if (x.getExclusiveUserId() != null && x.getExclusiveUserId() > 0) {
                if (id2Po.containsKey(x.getExclusiveUserId())) {
                    UserPO po = id2Po.get(x.getExclusiveUserId());
                    x.setExclusiveUserInfo(po.getNickName() + "/" + hideMobile(po.getMobile()));
                }
            }
        });
    }

    @Override
    @Transactional
    public int addLockedStore(Long productId, int store, long version) {
        return productRepository.addLockedStore(productId, store, version);
    }

    @Override
    public int minusStore(Long productId, int store, long version) {
        return productRepository.minusStore(productId, store, version);
    }

    @Override
    public int updateStores(Long productId, int store, int lockedStore) {
        return productRepository.updateStores(productId, store, lockedStore);
    }

    @Override
    public ApiResult lockStore(Long productId, int num) {

        try {
            while (true) {
                ProductPO productPO = findById(productId);
                long version = productPO.getVersion();
                if (productPO.availableStore() < num) {
                    //库存不足
                    return ApiResult.resultWith(ResultCodeEnum.ILLEGAL_STATE, "商品库存不足");
                }
                int index = productRepository.addLockedStore(productPO.getProductId(), num, version);
                if (index > 0) {
                    return ApiResult.ok();
                }
            }
        } catch (Exception ex) {
            return ApiResult.resultWith(ResultCodeEnum.EXCEPTION);
        }
    }

    private String hideMobile(String mobile) {
        return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    @Override
    public PageDataVO<ProductApiVo> search(ProductApiSearchCondition condition) {
        String sql = "select a.*,c.title as shopName from zb_product as a left join zb_category as b on a.cat_id = b.cat_id left join zb_merchant as c on c.merchant_id = a.merchant_id where delete_flag=0 and sale_type=0";
        String orderBy = "";
        String asc = "";
        if (condition.getSortType().equals(ProductEnums.DataSortField.DEFAULT.getCode())) {
            orderBy = " ORDER BY a.product_id desc ";
        } else if (condition.getSortType().equals(ProductEnums.DataSortField.PRICE.getCode())) {
            orderBy = " ORDER BY a.price ";
            asc = "asc";
        }

        if (condition.getSortField() != null && condition.getSortField().equals(ProductEnums.DataSortField.PRICE.getCode())) {
            orderBy = " ORDER BY a.price ";
            asc = "asc";
        }

        if (condition.getSortField() != null && condition.getSortField().equals(ProductEnums.DataSortField.TIME.getCode())) {
            orderBy = " ORDER BY a.create_time ";
            asc = "desc";
        }


        if (!StringUtils.isEmpty(orderBy)) {
            orderBy += (condition.getSortType().equals(0) ? asc : "desc");
        }
        String sqlWhere = "";
        if (condition.getMerchantId() != null && condition.getMerchantId() > 0) {
            sqlWhere += String.format(" and a.merchant_id=%s", condition.getMerchantId().toString());
        }

        //过滤直播专属商品
        if (condition.getPublicity() != null && condition.getPublicity().equals(0)) {
            sqlWhere += " and (a.exclusive_user_id is null or a.exclusive_user_id = 0)";

        }
        if (!StringUtils.isEmpty(condition.getKeyword())) {
            sqlWhere += " and a.product_name like '%" + condition.getKeyword().replace("'", "") + "%'";
        }

        if (condition.getCatId() != null && condition.getCatId() > 0) {
            CategoryPO categoryPO = categoryRepository.findById(condition.getCatId()).orElse(null);
            if (categoryPO != null) {
                sqlWhere += " and b.tree_path like '" + categoryPO.getTreePath() + "%'";
            }
        }
        if (condition.getRoomId() != null && condition.getRoomId() > 0) {
            sqlWhere += String.format(" and a.room_id=%s", condition.getRoomId().toString());
            //只获取有库存的商品
            sqlWhere += " and a.store - a.freeze >0 ";
        }

        if (condition.getProductType() != null) {
            sqlWhere += String.format(" and a.product_type=%s", condition.getProductType().toString());
        }
        if (condition.getTags() != null && condition.getTags().size() > 0) {
            String c = "";
            for (Integer tag : condition.getTags()) {
                c += " a.product_tags like '%," + tag + ",%' or ";
            }
            c += " 1<>1 ";
            sqlWhere += " and (" + c + ")";
        }
        if (condition.getStatusCode() != null) {
            sqlWhere += String.format(" and a.status_code=%s", condition.getStatusCode().toString());
        }

        if (condition.getRecommendFlag() != null && condition.getRecommendFlag().equals(1)) {
            sqlWhere += " and a.recommend_flag=1";
        }

        PageDataVO<SqlDataReader> pageReader = this.executePageList(sql + sqlWhere + orderBy, condition.getSize(), condition.getPage());
        return this.convertPageData(pageReader, this::convertDataReader2Vo);
    }

    @Override
    public ProductApiDetailVo getDetail(Long productId) {
        String sql = "select a.*,b.cat_name,'' as shopName from zb_product as a left join zb_category as b on a.cat_id = b.cat_id where delete_flag=0 and product_id=" + productId;
        SqlDataReader dataReader = this.executeReader(sql);
        ProductApiVo vo = this.convertDataReader2Vo(dataReader);

        MerchantPO merchantPO = merchantService.findById(vo.getMerchantId());
        if (merchantPO != null) {
            vo.setShopName(merchantPO.getData().getTitle());
        }

        ProductApiDetailVo detailVo = ProductMapStruct.INSTANCE.apiVo2DetailVo(vo);
        detailVo.setDetailContent(dataReader.getString("detail_content"));
        detailVo.setEnableNationwidePostingFree(detailVo.getServiceTags().contains(ProductEnums.ServiceTag.FREE_SHIPPING_NATIONALLY.getCode().toString()));
        detailVo.setEnable7DaysReturnedPurchase(detailVo.getServiceTags().contains(ProductEnums.ServiceTag.SEVEN_DAYS_NO_REASON_TO_REFUND.getCode().toString()));
        detailVo.setProductTagNames(getTagNames(detailVo.getProductTags(), ProductEnums.ProductTag.class));
        detailVo.setServiceTagNames(getTagNames(detailVo.getServiceTags(), ProductEnums.ServiceTag.class));
        List<ProductImgPO> imgPOList = productImgRepository.findAllByProductIdOrderBySortNoAsc(productId);
        List<String> picList = new ArrayList<>();
        imgPOList.forEach(x -> picList.add(x.getBig()));
        detailVo.setPicList(picList);
        return detailVo;
    }

    private List<String> getTagNames(String tags, Class<? extends CodeDescCommonEnum> cls) {
        if (StringUtils.isEmpty(tags)) {
            return new ArrayList<>();
        }
        String[] arr = StringUtilsExt.trim(tags, ',').split(",");
        List<String> nameList = new ArrayList<>();
        for (String s : arr) {
            if (StringUtils.isEmpty(s)) {
                continue;
            }
            nameList.add(CodeDescEnumHelper.getEnumDescByCode(cls, new Integer(s)).toString());
        }
        return nameList;
    }

    private ProductApiVo convertDataReader2Vo(SqlDataReader reader) {
        ProductApiVo apiVo = new ProductApiVo();
        apiVo.setProductId(reader.getLong("product_id"));
        apiVo.setMerchantId(reader.getLong("merchant_id"));
        apiVo.setProductName(reader.getString("product_name"));
        apiVo.setProductType(reader.getInteger("product_type"));
        apiVo.setCatId(reader.getInteger("cat_id"));
        apiVo.setPropSize(reader.getString("prop_size"));
        apiVo.setPropMaterial(reader.getString("prop_material"));
        apiVo.setLocation(reader.getString("location"));
        apiVo.setWeightUnit(reader.getString("weight_unit"));
        apiVo.setWeight(reader.getBigDecimal("weight"));
        apiVo.setPrice(reader.getBigDecimal("price"));
        apiVo.setMktPrice(reader.getBigDecimal("mkt_price"));
        apiVo.setServiceTags(reader.getString("service_tags"));
        apiVo.setLimitedNum(reader.getInteger("limited_num"));
        apiVo.setMainPic(reader.getString("main_pic"));
        apiVo.setVideo(reader.getString("video"));
        int store = reader.getInteger("store") - reader.getInteger("freeze");
        apiVo.setStore(Math.max(store, 0));
        apiVo.setProductTags(reader.getString("product_tags"));
        apiVo.setCommissionRate(reader.getBigDecimal("commission_rate"));
        apiVo.setRoomId(reader.getLong("room_id"));
        apiVo.setShopName(reader.getString("shopName"));
        apiVo.setRecommendFlag(reader.getInteger("recommend_flag"));
        return apiVo;
    }

    private ApiResult addNormalProduct(NormalProductSaveDTO saveDTO) {
        //1、各类校验
        ApiResult validateResult = validateNormalSaveDTO(saveDTO);
        if (!validateResult.isSuccess()) {
            return validateResult;
        }
        MerchantPO merchantPO = merchantService.findById(saveDTO.getMerchantId());
        if (merchantPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "商家不存在");
        }
        ProductPO preSavePO = (ProductPO) validateResult.getData();
        List<String> pics = preSavePO.getArrPics();
        if (pics == null || pics.size() == 0) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "请上传商品图片");
        }

        //2、添加
        preSavePO.setMerchantPO(merchantPO);
        preSavePO.preInsert();
        preSavePO.setSortNo(50);
        preSavePO.setSaleType(saveDTO.getSaleType());
        preSavePO.setAuctionStatus(AuctionEnums.AuctionStatus.TO_START);
        preSavePO.setServiceTags(processTagStr(preSavePO.getServiceTags()));
        preSavePO.setProductTags(processTagStr(preSavePO.getProductTags()));
        preSavePO.setRecommendFlag(preSavePO.getRecommendFlag() == null ? 0 : preSavePO.getRecommendFlag());
        preSavePO.setStatusCode(preSavePO.getStatusCode() == null ? 1 : preSavePO.getStatusCode());
        preSavePO = productRepository.saveAndFlush(preSavePO);
        //3、图片保存
        this.saveProductImages(preSavePO.getProductId(), merchantPO.getMerchantId(), pics);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, preSavePO);
    }

    private String processTagStr(String tags) {
        if (StringUtils.isEmpty(tags)) {
            return tags;
        }
        return "," + StringUtilsExt.trim(tags, ',') + ",";
    }

    private ApiResult editNormalProduct(NormalProductSaveDTO saveDTO) {
        //1、各类校验
        ApiResult validateResult = validateNormalSaveDTO(saveDTO);
        if (!validateResult.isSuccess()) {
            return validateResult;
        }
        ProductPO preSavePO = (ProductPO) validateResult.getData();
        ProductPO existPO = productRepository.findById(saveDTO.getProductId()).orElse(null);
        if (existPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "产品不存在");
        }

        //2、修改
        existPO.preUpdate();
        existPO.setCategory(preSavePO.getCategory());
        existPO.setMainPic(preSavePO.getMainPic());
        existPO.setCommissionRate(preSavePO.getCommissionRate());
        existPO.setDetailContent(saveDTO.getDetailContent());
        existPO.setLimitedNum(saveDTO.getLimitedNum());
        existPO.setLocation(saveDTO.getLocation());
        existPO.setMktPrice(saveDTO.getMktPrice());
        existPO.setPrice(saveDTO.getPrice());
        existPO.setProductName(saveDTO.getProductName());
        existPO.setProductType(saveDTO.getProductType());
        existPO.setSaleType(saveDTO.getSaleType());
        existPO.setPropMaterial(saveDTO.getPropMaterial());
        existPO.setPropSize(saveDTO.getPropSize());
        existPO.setSortNo(saveDTO.getSortNo());
        existPO.setStore(saveDTO.getStore());
        existPO.setVideo(saveDTO.getVideo());
        existPO.setWeight(saveDTO.getWeight());
        existPO.setWeightUnit(saveDTO.getWeightUnit());
        existPO.setServiceTags(processTagStr(preSavePO.getServiceTags()));
        existPO.setProductTags(processTagStr(preSavePO.getProductTags()));
        if (saveDTO.getStatusCode() != null) {
            existPO.setStatusCode(saveDTO.getStatusCode());
        }
        if (saveDTO.getMerchantId() == null || saveDTO.getMerchantId() == 0) {
            UserDetails userDetails = AuthHelper.getPrincipal();
            if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
                existPO.setRecommendFlag(saveDTO.getRecommendFlag());
            }
        } else {
            existPO.setRecommendFlag(saveDTO.getRecommendFlag());
        }
        productRepository.save(existPO);
        //3、图片保存
        this.saveProductImages(existPO.getProductId(), existPO.getMerchantPO().getMerchantId(), preSavePO.getArrPics());
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }

    private ApiResult validateNormalSaveDTO(NormalProductSaveDTO saveDTO) {
        if (saveDTO.getMerchantId() == null || saveDTO.getMerchantId() == 0) {
            UserDetails userDetails = AuthHelper.getPrincipal();
            if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
                saveDTO.setMerchantId(userDetails.getId());
            }
        }
        MerchantPO merchantPO = merchantService.findById(saveDTO.getMerchantId());
        if (merchantPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "商家不存在");
        }

        CategoryPO mainCategory = merchantPO.getData().getMainCategory();
        if (mainCategory == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "商家主目录未设置");
        }

        if (merchantPO.getCommissionRate() != null && MathUtils.greater(merchantPO.getCommissionRate(), BigDecimal.ZERO) && saveDTO.getCommissionRate().compareTo(merchantPO.getCommissionRate()) < 0) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, String.format("佣金比例不能小于商户设定值%s", merchantPO.getCommissionRate()));
        }


        if (mainCategory.getCommissionRate() != null && MathUtils.greater(mainCategory.getCommissionRate(), BigDecimal.ZERO) && saveDTO.getCommissionRate().compareTo(mainCategory.getCommissionRate()) < 0) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, String.format("佣金比例不能小于二级类目设定值%s", mainCategory.getCommissionRate()));
        }
        if (mainCategory.getCommissionRate() == null || MathUtils.lessAndEqual(mainCategory.getCommissionRate(), BigDecimal.ZERO)) {
            CategoryPO rootCategory = getRootCategory(mainCategory);
            if (rootCategory == null) {
                return ApiResult.errorWith(ResultCodeEnum.ERROR, "未能获取分类跟节点");
            }

            if (saveDTO.getCommissionRate().compareTo(rootCategory.getCommissionRate()) < 0) {
                return ApiResult.errorWith(ResultCodeEnum.ERROR, String.format("佣金比例不能小于一级类目设定值%s", rootCategory.getCommissionRate()));
            }
        }

        if (StringUtils.isNotBlank(saveDTO.getLocation()) && !RegexUtils.isChineseWord(saveDTO.getLocation())) {
            saveDTO.setLocation("");
//            throw new ApiException(ApiResult.error("源产地只支持输入汉字"));
        }


        List<String> picList = new ArrayList<>();
        String mainPic = "";
        if (!StringUtils.isEmpty(saveDTO.getPicList()) && !saveDTO.getPicList().equals("[]")) {
            picList = JSON.parseArray(saveDTO.getPicList(), String.class);
            if (picList != null && picList.size() > 0) {
                mainPic = picList.get(0);
            }
        }
        CategoryPO categoryPO = categoryRepository.getOne((long) saveDTO.getCatId());
        if (categoryPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "分类不存在");
        }
        ProductPO po = ProductMapStruct.INSTANCE.normalDto2Po(saveDTO);
        po.setMainPic(mainPic);
        po.setArrPics(picList);
        po.setCategory(categoryPO);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, po);
    }

    private CategoryPO getRootCategory(CategoryPO category) {
        String[] nodeList = StringUtilsExt.trim(category.getTreePath(), '|').split("\\|");
        if (org.springframework.util.StringUtils.isEmpty(nodeList[0])) {
            return null;
        }
        return categoryRepository.findById(new Long(nodeList[0])).orElse(null);
    }

    private ApiResult addLiveProduct(LiveProductSaveDTO saveDTO) {

        //1、各类校验
        ApiResult validateResult = validateLiveSaveDTO(saveDTO);
        if (!validateResult.isSuccess()) {
            return validateResult;
        }
        MerchantPO merchantPO = merchantService.findById(saveDTO.getMerchantId());
        if (merchantPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "商家不存在");
        }

        ProductPO preSavePO = (ProductPO) validateResult.getData();
        List<String> pics = preSavePO.getArrPics();

        if (pics == null || pics.size() == 0) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "缺少商品主图");
        }


        //2、添加
        preSavePO.setMerchantPO(merchantPO);
        preSavePO.preInsert();
        if (preSavePO.getLimitedNum() == null) {
            preSavePO.setLimitedNum(0);
        }
        preSavePO.setStatusCode(1);
        preSavePO.setSortNo(50);
        preSavePO.setSaleType(saveDTO.getSaleType());
        preSavePO = productRepository.saveAndFlush(preSavePO);
        //3、图片保存
        this.saveProductImages(preSavePO.getProductId(), merchantPO.getMerchantId(), pics);

        /**
         * 添加商品时，如果指定专属用户ID，则发送消息通知
         */
        if (saveDTO.getExclusiveUserId() != null && saveDTO.getExclusiveUserId() > 0) {
            tencentIMService.sendGoodsTarget(GoodsTargetMessageDTO.builder()
                    .productId(preSavePO.getProductId())
                    .roomId(saveDTO.getRoomId())
                    .userId(saveDTO.getExclusiveUserId()).build());
        }

        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }

    private ApiResult editLiveProduct(LiveProductSaveDTO saveDTO) {
        //1、各类校验
        ApiResult validateResult = validateLiveSaveDTO(saveDTO);
        if (!validateResult.isSuccess()) {
            return validateResult;
        }
        ProductPO preSavePO = (ProductPO) validateResult.getData();
        ProductPO existPO = productRepository.findById(saveDTO.getProductId()).orElse(null);
        if (existPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "产品不存在");
        }
        //2、修改
        existPO.preUpdate();
        existPO.setMainPic(preSavePO.getMainPic());
        if (saveDTO.getLimitedNum() == null) {
            existPO.setLimitedNum(0);
        } else {
            existPO.setLimitedNum(saveDTO.getLimitedNum());
        }
        existPO.setStatusCode(1);
        existPO.setPrice(saveDTO.getPrice());
        existPO.setProductName(saveDTO.getProductName());
        existPO.setSaleType(saveDTO.getSaleType());
        existPO.setPropSize(saveDTO.getPropSize());
        existPO.setServiceTags(saveDTO.getServiceTags());
        existPO.setSortNo(50);
        existPO.setStore(saveDTO.getStore());
        existPO.setExclusiveUserId(saveDTO.getExclusiveUserId());
        productRepository.save(existPO);
        //3、图片保存
        this.saveProductImages(existPO.getProductId(), existPO.getMerchantPO().getMerchantId(), preSavePO.getArrPics());

        /**
         * 修改商品时，如果指定专属用户ID，则发送消息通知
         */
        if (saveDTO.getExclusiveUserId() != null && saveDTO.getExclusiveUserId() > 0) {
            tencentIMService.sendGoodsTarget(GoodsTargetMessageDTO.builder()
                    .productId(preSavePO.getProductId())
                    .roomId(saveDTO.getRoomId())
                    .userId(saveDTO.getExclusiveUserId()).build());
        }


        return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
    }

    private ApiResult validateLiveSaveDTO(LiveProductSaveDTO saveDTO) {
        UserDetails userDetails = AuthHelper.getPrincipal();
        if (userDetails.getRoleType() == RoleEnum.MERCHANT) {
            saveDTO.setMerchantId(userDetails.getId());
        }
        MerchantPO merchantPO = merchantService.findById(saveDTO.getMerchantId());
        if (merchantPO == null) {
            return ApiResult.errorWith(ResultCodeEnum.ERROR, "商家不存在");
        }
        List<String> picList = new ArrayList<>();
        String mainPic = "";
        if (saveDTO.getPicList() != null && !saveDTO.getPicList().equals("") && !saveDTO.getPicList().equals("[]")) {
            picList = JSON.parseArray(saveDTO.getPicList(), String.class);
            if (picList != null && picList.size() > 0) {
                mainPic = picList.get(0);
            }
        }
        if (mainPic == null || mainPic.length() == 0) {
            throw new ApiException(ApiResult.error("缺少商品主图"));
        }
        ProductPO po = ProductMapStruct.INSTANCE.liveDto2Po(saveDTO);
        po.setMainPic(mainPic);
        po.setArrPics(picList);
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, po);
    }

    private void saveProductImages(Long productId, Long merchantId, List<String> picList) {
        productImgRepository.deleteByProductId(productId);
        for (String pic : picList) {
            ProductImgPO po = new ProductImgPO();
            po.setBig(pic);
            po.setSmall(pic);
            po.setThumbnail(pic);
            po.setMerchantId(merchantId);
            po.setProductId(productId);
            productImgRepository.save(po);
        }
    }


    @Override
    public boolean checkProductExistByCategoryId(Long categoryId) {
        return productRepository.countByCategory(categoryId) > 0;
    }
}